/*
 * @Descripttion:常用工具类
 */
import dayjs from 'dayjs';

type StrOrNum = string | number

export * from './animate';
export * from './theme';

/**
 * @description: 利用dayjs格式化时间
 * @param {Date} time 时间
 * @param {string} format 格式 YYYY-MM-DD HH:mm:ss
 * @return {*}
 */
export const formatDate = (time: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss') => dayjs(time).format(format);

/**
 * @description: 判断传入内容是否是 undefined、null或者空字符串
 * @param {array} str
 */
export const isEmpty = (...str: Array<any>): boolean => str.some((i) => i === undefined || i === null || i === '');

/**
 * @description: 复制
 * @param {*} copyInfo
 */
export const copyHandle = (copyInfo: string): void => {
  const $textarea = document.createElement('textarea');
  $textarea.value = copyInfo;
  document.body.appendChild($textarea);
  $textarea.select();
  document.execCommand('Copy'); // 执行浏览器复制命令
  $textarea.style.display = 'none';
  document.body.removeChild($textarea);
};

/**
 * @description: 通过图片获取网速
 * @param {*} fileSize 单位KB
 * @return B/ms
 */
export const getSpeedWithImg = (imgUrl: string, fileSize: number): any => new Promise((resolve) => {
  const start = Date.now();
  let end = null;
  const img = document.createElement('img');
  img.onload = () => {
    end = Date.now();
    const speed = (fileSize * 1000) / (end - start);
    resolve(speed);
  };
  img.src = imgUrl;
}).catch((err) => { throw err; });

/**
 * @description: 获取两个日期之间的所有日期
 * @param {Date} startTime GMT日期格式
 * @param {Date} endTime GMT日期格式
 */
export const getAllDateCN = (startTime: Date, endTime: Date) => {
  const dateAll = [];
  let i = 0;
  while (endTime.getTime() - startTime.getTime() >= 0) {
    // 获取日期和时间
    const year = startTime.getFullYear();
    const month = startTime.getMonth() + 1;
    const day = startTime.getDate();
    const time = startTime.toLocaleTimeString();

    const fullMonth = month < 10 ? `0${month}` : month;
    const fullDay = day < 10 ? `0${day}` : day;
    dateAll[i] = `${year}-${fullMonth}-${fullDay} ${time}`;

    // 天数+1
    startTime.setDate(startTime.getDate() + 1);
    i += 1;
  }
  return dateAll;
};

/**
 * @description: 求两个数组的交集
 * @param {StrOrNum} arrayFirst
 * @param {StrOrNum} arraySecond
 */
export const intersection = (arrayFirst: StrOrNum[], arraySecond: StrOrNum[]) => {
  const matched = arrayFirst.filter((af: string | number) => arraySecond.some((as: string | number) => af === as));
  return matched;
};

/**
 * @description: 求两个数组的并集
 * @param {StrOrNum} arrayFirst
 * @param {StrOrNum} arraySecond
 */
export const union = (arrayFirst: StrOrNum[], arraySecond: StrOrNum[]) => {
  const combinedArray = [...arrayFirst, ...arraySecond];
  return Array.from(new Set(combinedArray));
};

/**
 * @description: 颜色转换
 * @param {string} color 16进制颜色
 * @return {object} RGB对象
 */
export const parseColor = (color: string) => {
  const r = parseInt(color.substr(1, 2), 16) / 255;
  const g = parseInt(color.substr(3, 2), 16) / 255;
  const b = parseInt(color.substr(5, 2), 16) / 255;
  return { r, g, b };
};

/**
 * @description: 颜色转换
 * @param {string} color rgb颜色
 * @return {object} RGB对象
 */
export const parseRgbColor = (color: string) => {
  const rgb = color.match(/\d+/g) || [];
  if (rgb.length) {
    return {
      r: Number(rgb[0]),
      g: Number(rgb[1]),
      b: Number(rgb[2]),
    };
  }
  return {
    r: 0,
    g: 0,
    b: 0,
  };
};

/**
 * @description: 随机颜色
 * @param {boolean} is16 是否16进制
 * @return {string}
 */
export const getRandomColor = (is16 = false): string => {
  if (is16) {
    const letters = '0123456789ABCDEF';
    let color = '#';
    for (let i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
  }

  const r = Math.floor(Math.random() * 256);
  const g = Math.floor(Math.random() * 256);
  const b = Math.floor(Math.random() * 256);
  if (r === g && r === b) { // 避免生成灰色
    return getRandomColor(is16);
  }
  return `rgb(${r},${g},${b})`;
};

/**
 * @description: 颜色相似度
 * @param {string} color1 颜色
 * @param {string} color2 颜色
 * @param {number} num 默认值0.6，表示60%相似，颜色相似度阀值
 * @return {boolean}
 */

export const compareColor = (color1: string, color2: string, num = 0.6) => {
  const c1 = color1.startsWith('#') ? parseColor(color1) : parseRgbColor(color1);
  const c2 = color2.startsWith('#') ? parseColor(color2) : parseRgbColor(color2);
  const difference = Math.sqrt(
    (c1.r - c2.r) ** 2
    + (c1.g - c2.g) ** 2
    + (c1.b - c2.b) ** 2
  );
  return 1 - difference > num; // 根据需要设置相似度阈值
};

/**
 * 获取多边形中心点
 * @param {Point[]} points 点坐标数组 [{x:0,y:0}...]
 */
export const getPolygonCenter = (points: TypeObject[]): TypeObject => {
  if (!Array.isArray(points) || points.length < 3) {
    throw new Error('多边形坐标集合不能少于3个');
  }
  const result = { x: 0, y: 0 };
  points.forEach((p) => {
    result.x += p.x;
    result.y += p.y;
  });
  result.x /= points.length;
  result.y /= points.length;
  return result;
};

/**
 * @description: 格式化时间
 * @param {Date} time 时间
 * @param {string} cFormat 格式
 */
export function parseTime(time: Date | string | number, cFormat?: string): string {
  if (arguments.length === 0) {
    return '';
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date;
  if (typeof time === 'object') {
    date = time;
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time);
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time *= 1000;
    }
    date = new Date(time);
  }
  if (!date) {
    return '';
  }
  const formatObj: Record<any, any> = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value];
    }
    if (result.length > 0 && value < 10) {
      value = `0${value}`;
    }
    return value || 0;
  });
  return timeStr;
}
